/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ufps.cuatro.controlador.window;

import com.ufps.cuatro.CuatroApp;
import com.ufps.cuatro.modelo.representacion.componente.ComponenteDistribuidor;
import com.ufps.cuatro.modelo.representacion.componente.ComponenteDistribuidorGenerador;
import com.ufps.cuatro.modelo.representacion.ObjetoTipoDatoReflexion;
import com.ufps.cuatro.vistas.JDialogSeleccionTipoDatoGenerico;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JDialog;

/**
 *
 * @author Carlos A. Torres C. 
 */
public abstract class UtilWindow {
    
    /**
     *
     * @param objParent
     * @param strClassPath
     * @param varArgs
     * @return
     */
    public static boolean openDialog(Object objParent, String strClassPath, Object... varArgs){
        JDialog objDialogGeneric = null;
        try {           
            if(strClassPath.equals("JDialogSeleccionTipoDatoGenerico")){
                ArrayList<ObjetoTipoDatoReflexion> objTiposGenericos = (ArrayList<ObjetoTipoDatoReflexion>) varArgs[0];
                JDialogSeleccionTipoDatoGenerico objDialog = 
                        new JDialogSeleccionTipoDatoGenerico(objParent, objTiposGenericos);
                objDialogGeneric = objDialog;
            }  
            else if(strClassPath.equals("JDialogSeleccionComponenteParaBeans")){
                if(varArgs[0] instanceof ObjetoTipoDatoReflexion){
                    ObjetoTipoDatoReflexion objTipoDatoGenerico = (ObjetoTipoDatoReflexion) varArgs[0];
//                    JDialogSeleccionComponente objDialog = 
//                        new JDialogSeleccionComponente(objParent, objTipoDatoGenerico);
//                    objDialogGeneric = objDialog;
                }
                else if(varArgs[0] instanceof ComponenteDistribuidorGenerador){
                    ComponenteDistribuidorGenerador objComponenteGenerador = (ComponenteDistribuidorGenerador) varArgs[0];
//                    JDialogSeleccionComponente objDialog = 
//                        new JDialogSeleccionComponente(objParent, objComponenteGenerador);
//                    objDialogGeneric = objDialog;
                }
            }            
            else{
                return false;
            }
            objDialogGeneric.setLocationRelativeTo((java.awt.Window) objParent);
            objDialogGeneric.setModal(true);
            CuatroApp.getApplication().show(objDialogGeneric);
            return true;
        } catch (Exception ex) {
            Logger.getLogger(UtilWindow.class.getName()).log(Level.SEVERE, null, ex);
        }        
        return false;
    }
    
    /**
     *
     * @param objParent
     * @param objClass
     * @param arg
     * @return
     */
    public static boolean openDialog(Object objParent, Class<?> objClass, Object arg){
       try{
        Object varArgs[] = {objClass, arg};
        if(varArgs.length == 1){//Sin Parametros            
            return openDialog(objParent, objClass);
        }
        else{
            //Se Obtienen los Constructores
            Constructor<?>[] objConstructores = objClass.getDeclaredConstructors();
            ArrayList<Constructor<?>> objConstructoresValidos = devolverConstructoresValidos(objConstructores, varArgs.length);
            if(!objConstructoresValidos.isEmpty()){
                Constructor<?> objConstructor = devolverConstructorCandidato(objConstructores, varArgs);        
                objConstructor.setAccessible(true);
                try {
                    JDialog objDialoGeneric = (JDialog) objConstructor.newInstance(varArgs);
                    return open(objParent, objDialoGeneric);
                } catch (InstantiationException ex) {
                    Logger.getLogger(UtilWindow.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IllegalAccessException ex) {
                    Logger.getLogger(UtilWindow.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IllegalArgumentException ex) {
                    Logger.getLogger(UtilWindow.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InvocationTargetException ex) {
                    Logger.getLogger(UtilWindow.class.getName()).log(Level.SEVERE, null, ex);
                }
            }            
        }
        }catch(java.lang.NullPointerException ex){}
        return false;
    }
    
    private static Constructor<?> devolverConstructorCandidato(Constructor<?>[] objConstructores, Object... varArgs){        
        int parametrosCandidatos;
        for(Constructor<?> objConstructor : objConstructores){
            parametrosCandidatos = 0;
            for(int i = 0; i < objConstructor.getParameterTypes().length; i++){
                Class<?> objParametroConstructor = objConstructor.getParameterTypes()[i];
                Class<?> objVarArgs;
                if(varArgs[i] instanceof Class){
                    objVarArgs = (Class<?>) varArgs[i];
                }
                else{
                    objVarArgs = varArgs[i].getClass();
                }
                if((objParametroConstructor instanceof Object) && (varArgs[i] instanceof Class) && (i == 0)){
                    parametrosCandidatos++;
                }
                else if((varArgs[i] instanceof ComponenteDistribuidor) && (i > 0)){
                    parametrosCandidatos++;
                }
                else if(!objParametroConstructor.getCanonicalName().equals(objVarArgs.getCanonicalName())){                    
                    break;
                }                
                else{
                    parametrosCandidatos++;
                }
            }
            if(parametrosCandidatos == varArgs.length){
                return objConstructor;
            }            
        }
        return null;
    }
    
    private static ArrayList<Constructor<?>> devolverConstructoresValidos(Constructor<?>[] objConstructores, int size){
        ArrayList<Constructor<?>> objConstructoresValidos = new ArrayList<Constructor<?>>();
        for(Constructor<?> objConstructor : objConstructores){
            if(objConstructor.getParameterTypes().length == size){
                objConstructoresValidos.add(objConstructor);
            }
        }
        return objConstructoresValidos;
    }
    
    /**
     *
     * @param objParent
     * @param objClass
     * @return
     */
    public static boolean openDialog(Object objParent, Class<?> objClass){
       try{
            try {
                JDialog objDialogGeneric = (JDialog) objClass.newInstance();
                return open(objParent, objDialogGeneric);
            } catch (InstantiationException ex) {
                Logger.getLogger(UtilWindow.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                Logger.getLogger(UtilWindow.class.getName()).log(Level.SEVERE, null, ex);
            }
        }catch(java.lang.NullPointerException ex){}
        return false;
    }
    
    private static boolean open(Object objParent, JDialog objDialogGeneric){
        if(objParent == null){
            objDialogGeneric.setLocationRelativeTo(CuatroApp.getApplication().getMainFrame());
        }
        else{
            objDialogGeneric.setLocationRelativeTo((java.awt.Window) objParent);
        }
        objDialogGeneric.setModal(true);
        CuatroApp.getApplication().show(objDialogGeneric);
        return true;        
    }
}
